<?php


namespace app\api\model;

use http\Client;
use think\cache\driver\Redis;
use think\Db;
use think\Exception;
use think\facade\Log;
use util\Http;

class DouYinService
{
    protected $autoWriteTimestamp = true;
    protected $updateTime = false;

    protected $redis;
    protected $expireTime = 60 * 60;

    protected $douyin_url = 'https://open.douyin.com';

    const URL_TOKEN = 'https://open-api.ixigua.com/oauth/access_token/';

    protected $access_token = 'https://open-api.ixigua.com/oauth/access_token/';

    protected $client_token = 'https://open.douyin.com/oauth/client_token/';
    protected $open_ticket = 'https://open.douyin.com/open/getticket/';

    protected $schema = 'snssdk1128://openplatform/share';

    protected $share = 'https://open.douyin.com/share-id/';

    protected $item_url = 'https://open.douyin.com/api/douyin/v1/video/video_data/';

    //刷新refresh_token
    protected $refresh_token_url = 'https://open.douyin.com/oauth/renew_refresh_token/';
    //刷新access_token
    protected $access_token_url = 'https://open.douyin.com/oauth/refresh_token/';

    //获取视频数据
    protected $video_data_url = 'https://open.douyin.com/api/douyin/v1/video/video_data/';

    public function __construct()
    {
        $this->redis = (new Redis(config('token.redis')));
    }


    public function getClientToken()
    {
        $client_token = $this->redis->get('client_token');

        //获取client_token 并缓存1个小时
        if (empty($client_token)) {
            $data = [
                'client_key' => config('config_douyin.dy_program.client_key'),
                'client_secret' => config('config_douyin.dy_program.client_secret'),
                'grant_type' => 'client_credential'
            ];
            $res = Http::posturl($this->client_token . '?' . http_build_query($data));
            if ($res['message'] == 'success') {
                $client_token = $res['data']['access_token'];
                $this->redis->set('client_token', $client_token, $this->expireTime);
            } else {
                throw new Exception('获取getClientToken失败');
            }
        }
        return $client_token;
    }


    public function getOpenTicket($client_token)
    {
        $open_ticket = $this->redis->get('open_ticket');
        //获取client_token 并缓存1个小时
        if (empty($open_ticket)) {
            $headers = ["access-token: " . $client_token];
            $res = Http::getWithCurl($this->open_ticket, $headers);
            if ($res['data']['error_code'] == 0) {
                $open_ticket = $res['data']['ticket'];
                $this->redis->set('open_ticket', $open_ticket, $this->expireTime);
            } else {
                throw new Exception('获取getOpenTicket失败');
            }
        }
        return $open_ticket;
    }


    public function getShareId($client_token)
    {
        $arr = [
            'need_callback' => true,
        ];
        $url = $this->share . '?' . http_build_query($arr);
        $headers = ["access-token: " . $client_token];
        $res = Http::getWithCurl($url, $headers);
        if ($res['data']['error_code'] == 0) {
            $share_id = $res['data']['share_id'];
            return $share_id;
        } else {
            throw new Exception('获取getShareId失败');
        }
    }


    public function access_token($code)
    {
        $config = config('config_douyin.dy_program');
        $arr = [
            'client_secret' => $config['client_secret'],
            'client_key' => $config['client_key'],
            'code' => $code,
            'grant_type' => "authorization_code",
        ];
        $res = Http::posturl($this->access_token . '?' . http_build_query($arr));
        if ($res['message'] == 'success') {
            return $res;
        }
        return false;
    }

    public function getUserInfo($access_token, $openid)
    {
        $url = $this->douyin_url . '/oauth/userinfo/';
        $params = array(
            'access_token' => $access_token,
            'open_id' => $openid
        );
        $result = $this->curl_post($url, $params);
        return $result;
    }


    public function getNewRefreshToken($refresh_token)
    {
        $data = [
            'client_key' => config('config_douyin.dy_program.client_key'),
            'refresh_token' => $refresh_token
        ];
        $res = $this->curl_post($this->refresh_token_url, $data);
        if ($res['data']['error_code'] == 0) {
            return ['expires_in' => $res['data']['expires_in'], 'refresh_token' => $res['data']['refresh_token']];
        }
        return false;
    }


    public function getNewAccessToken($refresh_token)
    {
        $data = [
            'client_key' => config('config_douyin.dy_program.client_key'),
            'refresh_token' => $refresh_token,
            'grant_type' => 'refresh_token'
        ];
        $res = $this->curl_post($this->access_token_url, $data);
        if ($res['data']['error_code'] == 0) {
            return ['expires_in' => $res['data']['expires_in'], 'access_token' => $res['data']['access_token']];
        }
        return false;
    }


    public function getItemInfo($openid, $access_token, $item_id)
    {
        $headers = [
            'access-token' => $access_token,
            'content-type' => 'application/json'
        ];
        $data = array(
            'item_ids' => $item_id,
        );
        $client = new \GuzzleHttp\Client();
        $response = $client->post($this->video_data_url, [
            'headers' => $headers,
            'json' => $data,
            'query' => ['open_id' => $openid]
        ]);

        $body = $response->getBody();
        $result = json_decode($body, true);
        if ($result['data']['error_code'] == 0) {
            return $result['data']['list'];
        }
        return false;

    }


    public function curl_post($url, $postdata)
    {

        $header = array(
            'Accept: application/json',
        );

        //初始化
        $curl = curl_init();
        //设置抓取的url
        curl_setopt($curl, CURLOPT_URL, $url);
        //设置头文件的信息作为数据流输出
        curl_setopt($curl, CURLOPT_HEADER, 0);
        //设置获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        // 超时设置
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);

        // 超时设置，以毫秒为单位
        // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);

        // 设置请求头
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

        //设置post方式提交
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        //执行命令
        $data = curl_exec($curl);

        // 显示错误信息
        if (curl_error($curl)) {
            print "Error: " . curl_error($curl);
        } else {
            // 打印返回的内容
            curl_close($curl);

            return json_decode($data, true);
        }
    }

}